package me.ree.zkproduct.annotation;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Aspect
@Component
public class MethodCallCountAspect {

    private Map<String, AtomicInteger> methodCallCountMap = new ConcurrentHashMap<>();


    @Pointcut("@annotation(me.ree.zkproduct.annotation.MethodCallCount)")
//    @Pointcut("execution(* me.ree.zkproduct.manager.impl.*.*(..))")
    public void countMethodCallByAnnotation() {

    }

    @Around("countMethodCallByAnnotation()")
    public Object countMethodCallAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("countMethodCallAround begin...");
//        System.out.println("countMethodCallAround system out begin...");
        Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
        String methodName = method.getName();
        try {
            return proceedingJoinPoint.proceed();
        } finally {
            AtomicInteger count = methodCallCountMap.computeIfAbsent(methodName, k->new AtomicInteger(0));
            count.incrementAndGet();
            log.info("methodName={}, count={}", methodName, count.get());
        }
    }

    public int getMethodCallCount(String methodName) {
        AtomicInteger count = methodCallCountMap.get(methodName);
        return count != null ? count.get() : 0;
    }
}
